package com.libservice.screenshotservice

import android.app.Activity
import android.database.ContentObserver
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Log
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.libbase.Weak
import com.libservice.ScreenshotServiceInterface
import com.libservice.screenshotservice.ScreenshotEventDispatcher.handleMediaContentChange
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.lang.ref.WeakReference


class ScreenshotService : ScreenshotServiceInterface {

    private inner class MediaContentObserver(private val contentUri: Uri, handler: Handler?) :
        ContentObserver(handler) {
        override fun onChange(selfChange: Boolean) {
            super.onChange(selfChange)

            handleMediaContentChange(contentUri, activity, startListenTime, screenshotListener)
        }
    }

    private var startListenTime: Long = 0

    private var internalObserver: MediaContentObserver? = null

    private var externalObserver: MediaContentObserver? = null

    private val uiHandler = Handler(Looper.getMainLooper())

    private var activity: Activity? by Weak { null }

    override var screenshotListener: ScreenshotListener? by Weak { null }

    override suspend fun startListen(weakActivity: WeakReference<Activity>): Unit =
        withContext(Dispatchers.IO) {
            Log.i("ScreenShotService", "startListen")

            weakActivity.get()?.let {
                val xxPermissions = XXPermissions.with(it)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    xxPermissions.permission(Permission.READ_MEDIA_IMAGES)
                } else {
                    xxPermissions.permission(Permission.MANAGE_EXTERNAL_STORAGE)
                }
                xxPermissions.request { _, allGranted ->
                    if (allGranted) {
                        if (startListenTime == 0L) {
                            startListenTime = System.currentTimeMillis()
                            activity = it

                            registerObserver(it)
                        }
                    }
                }
            }
        }

    override suspend fun stopListen(weakActivity: WeakReference<Activity>): Unit =
        withContext(Dispatchers.IO) {
            activity?.let {
                Log.i("ScreenShotService", "stopListen")

                unregisterObserver(it)

                startListenTime = 0
                activity = null
            }
        }

    private fun registerObserver(activity: Activity) {
        Log.i("ScreenShotService", "registerObserver")

        internalObserver =
            MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, uiHandler)
        externalObserver =
            MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, uiHandler)

        activity.applicationContext.contentResolver.registerContentObserver(
            MediaStore.Images.Media.INTERNAL_CONTENT_URI,
            Build.VERSION.SDK_INT > Build.VERSION_CODES.P,
            internalObserver!!
        )

        activity.applicationContext.contentResolver.registerContentObserver(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            Build.VERSION.SDK_INT > Build.VERSION_CODES.P,
            externalObserver!!
        )
    }

    private fun unregisterObserver(activity: Activity) {
        Log.i("ScreenShotService", "unregisterObserver")

        internalObserver?.let {
            activity.applicationContext.contentResolver.unregisterContentObserver(it)
        }
        internalObserver = null

        externalObserver?.let {
            activity.applicationContext.contentResolver.unregisterContentObserver(it)
        }
        externalObserver = null
    }
}